package cn.akwangl.interceptor;

import com.alibaba.ttl.TransmittableThreadLocal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;


/**
 * {@link Logger}包装类,它会在每次打印日志之前会将系统日志Id打印出来,并不会影响其原来使用方式.<br/>
 * 为什么有了{@link Logger}还要对它进行包装呢?答案是它的功能并不能满足需求.<br/>
 * <p>
 * 假设现在有一个业务场景:
 * 一个系统有好几个服务,日志全部由elaticsearch(ES)来管理,当生产环境出现一个bug时你想排查问题,找日志是一件十分耗时耗力的事情.假如说一次http请求
 * 在每次日志打印前有一个全局Id,那么直接使用ES Query API 查询是一件幸福的事情,这个包装类就是起到这个作用.
 *
 * @author 阿坤同学
 * @date 2022/5/29 11:51
 * @since 0.0.4
 */
public class LoggerWrapper implements Logger {

    private Logger logger;

    public LoggerWrapper(Class<?> clazz) {
        this.logger = LoggerFactory.getLogger(clazz);
    }

    /**
     * 获取日志记录器.
     *
     * @param clazz 返回的记录器将以clazz命名
     * @return logger
     * @author 阿坤同学
     * @date 2022/5/29 13:40
     * @since 0.0.4
     */
    public static Logger getLogger(Class<?> clazz) {
        return new LoggerWrapper(clazz);
    }

    /**
     * 系统全局日志Id,访问权限设计为包权限.
     *
     * @author 阿坤同学
     * @date 2022/5/29 12:00
     * @since 0.0.4
     */
    private static TransmittableThreadLocal<String> globalSysLogIdThreadLocal = new TransmittableThreadLocal();

    /**
     * 清除全局日志Id.
     *
     * @author 阿坤同学
     * @date 2022/5/29 12:50
     * @since 0.0.4
     */
    void cleanGlobalSysLogId() {
        globalSysLogIdThreadLocal.remove();
        logger.info("系统全局日志Id已被清除");
    }

    /**
     * 设置全局日志Id.
     *
     * @author 阿坤同学
     * @date 2022/5/29 12:51
     * @since 0.0.4
     */
    void setGlobalSysLogId(String globalSysLogId) {
        globalSysLogIdThreadLocal.set(globalSysLogId);
    }

    @Override
    public String getName() {
        return logger.getName();
    }

    @Override
    public boolean isTraceEnabled() {
        return logger.isTraceEnabled();
    }

    @Override
    public void trace(String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.trace(newMsg);
    }

    @Override
    public void trace(String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.trace(newFormat, arg);
    }

    @Override
    public void trace(String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.trace(newFormat, arg1, arg2);
    }

    @Override
    public void trace(String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.trace(newFormat, arguments);
    }

    @Override
    public void trace(String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.trace(newMsg, t);
    }

    @Override
    public boolean isTraceEnabled(Marker marker) {
        return logger.isTraceEnabled(marker);
    }

    @Override
    public void trace(Marker marker, String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.trace(marker, newMsg);
    }

    @Override
    public void trace(Marker marker, String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.trace(marker, newFormat, arg);
    }

    @Override
    public void trace(Marker marker, String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.trace(marker, newFormat, arg1, arg2);
    }

    @Override
    public void trace(Marker marker, String format, Object... argArray) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.trace(marker, newFormat, argArray);
    }

    @Override
    public void trace(Marker marker, String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.trace(marker, newMsg, t);
    }

    @Override
    public boolean isDebugEnabled() {
        return logger.isDebugEnabled();
    }

    @Override
    public void debug(String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.debug(newMsg);
    }

    @Override
    public void debug(String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.debug(newFormat, arg);
    }

    @Override
    public void debug(String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.debug(newFormat, arg1, arg2);
    }

    @Override
    public void debug(String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.debug(newFormat, arguments);
    }

    @Override
    public void debug(String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.debug(newMsg, t);
    }

    @Override
    public boolean isDebugEnabled(Marker marker) {
        return logger.isDebugEnabled(marker);
    }

    @Override
    public void debug(Marker marker, String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.debug(marker, newMsg);
    }

    @Override
    public void debug(Marker marker, String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.debug(marker, newFormat, arg);
    }

    @Override
    public void debug(Marker marker, String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.debug(marker, newFormat, arg1, arg2);
    }

    @Override
    public void debug(Marker marker, String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.debug(marker, newFormat, arguments);
    }

    @Override
    public void debug(Marker marker, String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.debug(marker, newMsg, t);
    }

    @Override
    public boolean isInfoEnabled() {
        return logger.isInfoEnabled();
    }

    @Override
    public void info(String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.info(newMsg);
    }

    @Override
    public void info(String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.info(newFormat, arg);
    }

    @Override
    public void info(String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.info(newFormat, arg1, arg2);
    }

    @Override
    public void info(String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.info(newFormat, arguments);
    }

    @Override
    public void info(String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.info(newMsg, t);
    }

    @Override
    public boolean isInfoEnabled(Marker marker) {
        return logger.isInfoEnabled(marker);
    }

    @Override
    public void info(Marker marker, String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.info(marker, newMsg);
    }

    @Override
    public void info(Marker marker, String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.info(marker, newFormat, arg);
    }

    @Override
    public void info(Marker marker, String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.info(marker, newFormat, arg1, arg2);
    }

    @Override
    public void info(Marker marker, String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.info(marker, newFormat, arguments);
    }

    @Override
    public void info(Marker marker, String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.info(marker, newMsg, t);
    }

    @Override
    public boolean isWarnEnabled() {
        return logger.isWarnEnabled();
    }

    @Override
    public void warn(String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.warn(newMsg);
    }

    @Override
    public void warn(String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.warn(newFormat, arg);
    }

    @Override
    public void warn(String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.warn(newFormat, arguments);
    }

    @Override
    public void warn(String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.warn(newFormat, arg1, arg2);
    }

    @Override
    public void warn(String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.warn(newMsg, t);
    }

    @Override
    public boolean isWarnEnabled(Marker marker) {
        return logger.isWarnEnabled(marker);
    }

    @Override
    public void warn(Marker marker, String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.warn(marker, newMsg);
    }

    @Override
    public void warn(Marker marker, String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.warn(marker, newFormat, arg);
    }

    @Override
    public void warn(Marker marker, String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.warn(marker, newFormat, arg1, arg2);
    }

    @Override
    public void warn(Marker marker, String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.warn(marker, newFormat, arguments);
    }

    @Override
    public void warn(Marker marker, String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.warn(marker, newMsg, t);
    }

    @Override
    public boolean isErrorEnabled() {
        return logger.isErrorEnabled();
    }

    @Override
    public void error(String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.error(newMsg);
    }

    @Override
    public void error(String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.error(newFormat, arg);
    }

    @Override
    public void error(String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.error(newFormat, arg1, arg2);
    }

    @Override
    public void error(String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.error(newFormat, arguments);
    }

    @Override
    public void error(String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.error(newMsg, t);
    }

    @Override
    public boolean isErrorEnabled(Marker marker) {
        return logger.isErrorEnabled(marker);
    }

    @Override
    public void error(Marker marker, String msg) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.error(marker, newMsg);
    }

    @Override
    public void error(Marker marker, String format, Object arg) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.error(marker, newFormat, arg);
    }

    @Override
    public void error(Marker marker, String format, Object arg1, Object arg2) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.error(marker, newFormat, arg1, arg2);
    }

    @Override
    public void error(Marker marker, String format, Object... arguments) {
        String newFormat = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), format);
        logger.error(marker, newFormat, arguments);
    }

    @Override
    public void error(Marker marker, String msg, Throwable t) {
        String newMsg = String.format("系统日志Id:%s,%s", globalSysLogIdThreadLocal.get(), msg);
        logger.error(marker, newMsg, t);
    }
}